package crmdna.list;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import com.googlecode.objectify.annotation.Index;

import crmdna.common.Utils;

@Entity
public class ListShardEntity {

	@Id
	String listShardId;

	// e.x: 1||4
	// 1 is the list id, and 4 is the shard no

	@Index
	private Set<Long> elements = new HashSet<>();

	Set<Long> getElements() {
		return Collections.unmodifiableSet(elements);
	}

	boolean isSpaceAvailable() {
		return elements.size() < ListCore.MAX_ELEMENTS_PER_SHARD;
	}

	int getNumSpacesAvailable() {
		return ListCore.MAX_ELEMENTS_PER_SHARD - elements.size();
	}

	void addElement(long element) {
		if (!isSpaceAvailable()) {
			ListShardProp listShardProp = toProp();
			Utils.throwIncorrectSpecException("Cannot add element to shard no ["
					+ listShardProp.shardNo
					+ "] for list id ["
					+ listShardProp.listId
					+ "] as it already at maximum capacity with ["
					+ elements.size() + "] elements");
		}

		elements.add(element);
	}

	boolean deleteElements(Set<Long> toBeDeleted) {
		return elements.removeAll(toBeDeleted);
	}

	ListShardProp toProp() {
		return new ListShardProp(listShardId);
	}

	//
	void addMemberIds(Set<Long> toBeAdded) {
		int availableSpace = ListCore.MAX_ELEMENTS_PER_SHARD - elements.size();

		if (toBeAdded.size() > availableSpace)
			Utils.throwIncorrectSpecException("Attempt to add ["
					+ toBeAdded.size() + "] elements in a list shard with ["
					+ elements.size() + "] existing elements. Can only add ["
					+ availableSpace
					+ "] elements to prevent breaching the limit of ["
					+ ListCore.MAX_ELEMENTS_PER_SHARD + "] elements per shard");

		elements.addAll(toBeAdded);
	}

	boolean deleteMemberIds(Set<Long> toBeDeleted) {
		return elements.remove(toBeDeleted);
	}
	//
}
